<template>
  <div class="panel" v-if="modeler">
    <div class="content">
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="基本信息" name="first"></el-tab-pane>
        <el-tab-pane label="监听" name="second">
          <Listeners :modeler="modeler" @change="updateElementListener" />
        </el-tab-pane>
        <el-tab-pane label="扩展" name="third">
          <Expand
            :modeler="modeler"
            @change="updateElementAttributes"
            :elementAttributes="elementAttributes"
          />
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>

<script>
import Expand from "./Expand";
import Listeners from "./Listeners";
import { is } from "bpmn-js/lib/util/ModelUtil";

export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Index",
  components: {
    Expand,
    Listeners,
  },
  props: {
    modeler: {
      type: Object,
      default: () => ({}),
    },
  },

  data() {
    return {
      element: {},
      rootElement: null,
      flag: 1,
      activeName: "first",
      ruleForm: {},

      prefix: "camunda",
      elementRegistry: "",
      elementAttributes: [],
    };
  },

  computed: {
    elementId() {
      console.log(this.activeElementBusiness);
      if (this.activeElementBusiness) return this.activeElementBusiness.id;
      return null;
    },
  },

  methods: {
    handleClick() {},

    updateElementListener(listeners) {
      console.log(listeners);
      const matcher = (item) => !is(item, "camunda:ExecutionListener");

      let objectsToAdd = [listeners].map((row) => {
        const data = this.moddle.create("camunda:ExecutionListener");
        data.event = row.event;
        if (row.scriptType) {
          const attrs = {};
          attrs.scriptFormat = row.scriptFormat;
          if (this.showResource(row.scriptType)) {
            attrs.resource = row.listenerType;
          } else {
            attrs.value = row.listenerType;
          }
          data.script = this.moddle.create("camunda:Script", attrs);
        } else {
          data[row.listenerType] = row.listenerType;
        }
        if (row.fields?.length) {
          row.fields.forEach((field) => {
            const fieldElement = this.moddle.create("camunda:Field");
            fieldElement.name = field.name;
            fieldElement.value = field.value;
            fieldElement[field.type] = field.value;
            data.get("fields").push(fieldElement);
          });
        }
        return data;
      });
      const element = this.elementRegistry.get(this.elementId);

      let currentObject = this.moddle.create("bpmn:ExtensionElements", {
        values: [],
      });

      console.log(currentObject)

      const listCopy = objectsToAdd || [];

      if (matcher) {
        listCopy.push(...currentObject["values"].filter(matcher));
      } else {
        listCopy.push(...currentObject["values"]);
      }
      // set property to new list
      if (listCopy.length > 0) {
        // as long as there are elements in the list update the list
        currentObject.values = listCopy;
      } else {
        // remove the list when it is empty
        if (currentObject.$parent.extensionElements) {
          currentObject.$parent.extensionElements = undefined;
        }
        currentObject = undefined;
      }

      this.modeling.updateProperties(element, {
        extensionElements: currentObject,
      });
    },

    getBO() {
      console.log(this.bo);
      console.log(this.element);
      return {
        templateProperties: this.bo ? this.bo.templateProperties : undefined,
        ...this.element.businessObject,
      };
    },

    updateElementAttributes(attributes) {
      // attributes 是普通数组，需要重新创建实例
      const properties = this.moddle.create(`${this.prefix}:Properties`, {
        values: attributes.map((attr) => {
          return this.moddle.create(`${this.prefix}:Property`, {
            id: attr.id,
            name: attr.name,
            value: attr.value,
          });
        }),
      });

      const element = this.elementRegistry.get(this.elementId);

      const extensionElements = element.businessObject.get("extensionElements");
      // 截取不是扩展属性的属性
      const otherExtensions =
        (extensionElements &&
          extensionElements.get("values") &&
          extensionElements
            .get("values")
            .filter((ex) => ex.$type !== `${this.prefix}:Properties`)) ||
        [];

      // 重建扩展属性
      const extensions = this.moddle.create("bpmn:ExtensionElements", {
        values: otherExtensions.concat([properties]),
      });

      this.updateElementExtensions(element, extensions);
    },

    // 更新属性到元素
    updateElementExtensions(element, extensions, attributes) {
      this.modeling.updateProperties(element, {
        extensionElements: extensions,
      });
      // 更新表单
      // this.initFormOnChanged(this.elementId,attributes);
    },

    init() {
      this.modeler.on("selection.changed", (e) => {
        this.selectedElements = e.newSelection;
        this.element = e.newSelection[0];
        this.rootElement = null;
        this.setDefaultProperties(this.element);
      }),
        this.modeler.on("element.click", (e) => {
          if (!this.element) {
            this.rootElement = e.element;
            this.setDefaultProperties(this.rootElement);
          }
        });
    },

    setDefaultProperties(element) {},

    /**
     * 更新元素属性
     * @param { Object } 要更新的属性, 例如 { name: '' }
     */
    updateProperties(properties) {
      const modeling = this.modeler.get("modeling");
      modeling.updateProperties(
        this.element ? this.element : this.rootElement,
        properties
      );
    },

    // 监听 modeler
    addModelerListener() {
      this.modeling = this.modeler.get("modeling");
      this.moddle = this.modeler.get("moddle");
      this.eventBus = this.modeler.get("eventBus");
      this.bpmnFactory = this.modeler.get("bpmnFactory");
      this.elementRegistry = this.modeler.get("elementRegistry");
      this.replace = this.modeler.get("replace");
      this.selection = this.modeler.get("selection");

      const processElement = this.elementRegistry.find((el) => {
        return el.type == "bpmn:Process";
      });
      this.activeElementBusiness = Object.assign(
        {},
        processElement.businessObject
      );
      console.log("this", this.activeElementBusiness);
      // 注册事件 操作节点的各项事件
      const events = [
        "shape.added",
        "shape.move.end",
        "shape.removed",
        "connect.end",
        "connect.move",
      ];
      events.forEach((event) => {
        this.modeler.on(event, (e) => {
          // console.log('events e', e)
        });
      });
    },

    addEventBusListener() {
      // 需要监听的事件集合
      const eventTypes = ["element.click", "element.changed"];
      // 需要使用eventBus
      const eventBus = this.modeler.get("eventBus");
      eventTypes.forEach((eventType) => {
        eventBus.on(eventType, 1000, (e) => {
          const elementRegistry = this.modeler.get("elementRegistry");
          // 赋值元素
          const element = elementRegistry.get(e.element.id);
          this.activeElementBusiness = element;

          //  赋值监听和扩展属性
          if (
            element &&
            element.businessObject &&
            element.businessObject.extensionElements &&
            element.businessObject.extensionElements.values
          ) {
            console.log(element, "当前的");
            // this.elementListeners = element.businessObject.extensionElements.values.filter(
            //   ex => ex.$type === `${this.prefix}:ExecutionListener`
            // )
            this.elementAttributes =
              element.businessObject.extensionElements.values.filter(
                (ex) => ex.$type === `${this.prefix}:Properties`
              );

            // console.log('prefix', this.elementAttributes, this.prefix)
          } else {
            // this.elementListeners = []
            this.elementAttributes = [];
          }
        });
      });
    },
  },

  mounted() {
    // this.init();
    this.$nextTick(() => {
      this.addModelerListener();
      this.addEventBusListener();
    });
  },
};
</script>

<style lang="scss" scoped>
.panel {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 300px;
  z-index: 10;
  border-left: 1px solid #ccc;
  overflow: auto;
  background-color: #f8f8f8;
}
.content {
  padding: 0 16px;

  ::v-deep .el-form-item {
    margin-bottom: 0;
  }
  ::v-deep .el-form--label-top .el-form-item__label {
    padding: 0;
    float: left;
  }
}
</style>
